<?php
/**
 * Plugin Helper File
 *
 * @package     Tooltips
 * @version     0.3.3
 *
 * @author      Peter van Westen <peter@nonumber.nl>
 * @link        http://www.nonumber.nl
 * @copyright   Copyright © 2011 NoNumber! All Rights Reserved
 * @license     http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
 */

// No direct access
defined( '_JEXEC' ) or die();

/**
* Plugin that replaces stuff
*/
class plgSystemTooltipsHelper
{
	function __construct( &$params )
	{
		$this->params = $params;
		$this->params->hasitems = 0;

		$this->params->comment_start = '<!-- START: Tooltips -->';
		$this->params->comment_end = '<!-- END: Tooltips -->';

		$this->params->tag = preg_replace( '#[^a-z0-9-_]#s', '', $this->params->tag );
		$this->params->regex = '#\{'.preg_quote( $this->params->tag, '#' ).' ([^\}]*)\}(.*?)\{/'.preg_quote( $this->params->tag, '#' ).'\}#s';

		$this->params->protect_s = array( '{'.$this->params->tag, '{/'.$this->params->tag );
		$this->params->protect_r = array( $this->protectStr( $this->params->protect_s['0'] ), $this->protectStr( $this->params->protect_s['1'] ) ) ;
	}

////////////////////////////////////////////////////////////////////
// onAfterDispatch
////////////////////////////////////////////////////////////////////
	function onAfterDispatch()
	{
		$document =& JFactory::getDocument();
		$docType = $document->getType();

		// only in html
		if ( $docType !== 'html' && $docType !== 'feed' ) { return; }

		// do not load scripts/styles on print page
		if ( $docType !== 'feed' && !JRequest::getInt( 'print' ) && !JRequest::getInt( 'noscript' ) ) {
			$version = '';
			if ( $this->params->use_versioned_files ) {
				require_once JPATH_PLUGINS.DS.'system'.DS.'nonumberelements'.DS.'helpers'.DS.'versions.php';
				$version = NoNumberVersions::getXMLVersion( 'tooltips', 'system', null, 1 );
			}

			$script = '
				var tooltips_fade_in_speed = '.(int) $this->params->fade_in_speed.';
				var tooltips_fade_out_speed = '.(int) $this->params->fade_out_speed.';
				var tooltips_max_width = '.(int) $this->params->max_width.';
			';
			$document->addScriptDeclaration( preg_replace( '#\n\s*#s', ' ', $script ) );

			$document->addScript( JURI::root( true ).'/plugins/system/tooltips/js/script.js'.$version );

			if ( $this->params->load_stylesheet ) {
				$document->addStyleSheet( JURI::root( true ).'/plugins/system/tooltips/css/style.css'.$version );
			}
			if ( $this->params->underline ) {
				$css = 'span.tooltips-link { border-bottom: 1px '.$this->params->underline.' #'.$this->params->underline_color.'; }';
				$document->addStyleDeclaration( $css );
			}
			if ( $this->params->zindex ) {
				$css = 'div.tooltips-tip, div.tooltips-tip.tool-tip, div.tooltips-tip-tip { z-index: '.(int) $this->params->zindex.' }';
				$document->addStyleDeclaration( $css );
			}
			$css = array();
			$css[] = 'background-color: #'.strtoupper( $this->params->bg_color ).';';
			$css[] = 'border-color: #'.strtoupper( $this->params->border_color).';';
			$css[] = 'border-width: '.(int) $this->params->border_width.'px;';
			if ( $this->params->use_border_radius ) {
				$css[] = '-webkit-border-radius: '.(int)$this->params->border_radius.'px;';
				$css[] = '-moz-border-radius: '.(int)$this->params->border_radius.'px;';
				$css[] = 'border-radius: '.(int)$this->params->border_radius.'px;';
			}
			$css[] = 'max-width: '.(int) $this->params->max_width.'px;';

			$css = 'div.tooltips-tip div.tip, div.tooltips-tip-tip > div { '.implode( ' ', $css ).' }';
			$document->addStyleDeclaration( $css );

			$options = array();
			$options['showDelay'] = (int) $this->params->show_delay;
			$options['hideDelay'] = (int) $this->params->hide_delay;
			$options['fixed'] = ( $this->params->fixed );
			$options['className'] = 'tooltips-tip';
			$options['onShow'] = "function(tip){ tooltips_show( tip ); }";
			$options['onHide'] = "function(tip){ tooltips_hide( tip ); }";
			JHTML::_( 'behavior.tooltip', '.tooltips-link', $options );
			$options['className'] = 'tooltips-img tooltips-tip';
			JHTML::_( 'behavior.tooltip', '.tooltips-link-img', $options );
		}

		$buffer = $document->getBuffer( 'component' );

		if ( !$buffer || strpos( $buffer, '{'.$this->params->tag ) === false ) { return; }

		$this->params->hasitems = 1;

		$this->protect( $buffer );
		$this->replaceTags( $buffer );
		$this->unprotect( $buffer );

		$document->setBuffer( $buffer, 'component' );
	}

////////////////////////////////////////////////////////////////////
// onAfterRender
////////////////////////////////////////////////////////////////////
	function onAfterRender()
	{
		$document =& JFactory::getDocument();
		$docType = $document->getType();

		// only in html
		if ( $docType !== 'html' && $docType !== 'feed' ) { return; }

		$html = JResponse::getBody();
		if ( $html == '' ) { return; }

		if ( strpos( $html, '{'.$this->params->tag ) === false ) {
			if ( !$this->params->hasitems ) {
				// remove style and script if no items are found
				$html = preg_replace( '#\s*<'.'link rel="stylesheet" href="[^"]*/plugins/system/tooltips/css/style.css" type="text/css" />#s', '', $html );
			}
		} else {
			if ( !( strpos( $html, '<body' ) === false ) && !( strpos( $html, '</body>' ) === false ) ) {
				$html_split = explode( '<body', $html, 2 );
				$body_split = explode( '</body>', $html_split['1'], 2 );

				// only do the handling inside the body
				$this->protect( $body_split['0'] );
				$this->replaceTags( $body_split['0'] );
				$this->unprotect( $body_split['0'] );

				$html_split['1'] = implode( '</body>', $body_split );
				$html = implode( '<body', $html_split );
			} else {
				$this->protect( $html );
				$this->replaceTags( $html );
				$this->unprotect( $html );
			}
		}

		JResponse::setBody( $html );
	}

////////////////////////////////////////////////////////////////////
// FUNCTIONS
////////////////////////////////////////////////////////////////////
	function replaceTags( &$str )
	{
		if( strpos( $str, '{/'.$this->params->tag ) === false ) {
			if ( preg_match_all( $this->params->regex, $str, $matches, PREG_SET_ORDER ) > 0 ) {
				foreach ( $matches as $match ) {
					$str = str_replace( $match['0'], $match['2'], $str );
				}
			}
			return;
		}
		if ( preg_match_all( $this->params->regex, $str, $matches, PREG_SET_ORDER ) > 0 ) {
			foreach ( $matches as $match ) {
				$tip = $match['1'];
				$text = $match['2'];

				$classes = str_replace( '\|', '[:TT_BAR:]', $tip );
				$classes = explode( '|', $classes );
				foreach ( $classes as $i => $class ) {
					$classes[$i] = trim( str_replace( '[:TT_BAR:]', '|', $class ) );
				}
				$tip = array_shift( $classes );

				array_unshift( $classes, 'tooltips-link' );

				if ( preg_match_all( '#(src|href)="([^"]*)"#si', $tip, $url_matches, PREG_SET_ORDER ) > 0 ) {
					foreach ( $url_matches as $url_match ) {
						$url = $url_match['2'];
						if ( strpos( $url, 'http' ) !== 0 ) {
							$url = JURI::root().$url;
						}
						$url = $url_match['1'].'="'.$url.'"';
						$tip = str_replace( $url_match['0'], $url, $tip );
					}
				}
				$tip = explode( '::', $tip, 2 );
				if ( !isset( $tip['1'] ) && preg_match( '#^\s*(&lt;|<)img [^>]*(&gt;|>)\s*$#', $tip['0'] ) ) {
					$classes['0'] .= '-img';
				}
				$tip = str_replace( '"', '&quot;', implode( '::', $tip ) );
				if ( preg_match( '#^\s*<img [^>]*>\s*$#', $text ) ) {
					$classes[] = 'isimg';
				}
				$r = '<span class="'.implode( ' ', $classes ).'" title="'.$tip.'">'.$text.'</span>';
				$str = str_replace( $match['0'], $r, $str );
			}
		}
	}

	/*
	 * Protect admin form
	 */
	function protect( &$string )
	{
		if (	in_array( JRequest::getCmd( 'task' ), array( 'edit' ) )
			||	in_array( JRequest::getCmd( 'view' ), array( 'edit', 'form' ) )
			||	in_array( JRequest::getCmd( 'layout' ), array( 'edit', 'form', 'write' ) )
			||	in_array( JRequest::getCmd( 'option' ), array( 'com_contentsubmit', 'com_cckjseblod' ) )
		) {
			// Protect complete adminForm (to prevent articles from being created when editing articles and such)
			$unprotected = $this->params->protect_s;
			$protected = $this->params->protect_r;
			$string = preg_replace( '#(<'.'form [^>]*(id|name)="adminForm")#si', '<!-- TMP_START_EDITOR -->\1', $string );
			$string = explode( '<!-- TMP_START_EDITOR -->', $string );
			foreach ( $string as $i => $str ) {
				if ( !empty( $str ) != '' && fmod( $i, 2 ) ) {
					if ( !( strpos( $str, $unprotected['0'] ) === false ) || !( strpos( $str, $unprotected['1'] ) === false ) || !( strpos( $str, $unprotected['2'] ) === false ) ) {
						$str = explode( '</form>', $str, 2 );
						$str['0'] = str_replace( $unprotected, $protected, $str['0'] );
						$string[$i] = implode( '</form>', $str );
					}
				}
			}
			$string = implode( '', $string );
		}
	}

	function unprotect( &$str )
	{
		$str = str_replace( $this->params->protect_r, $this->params->protect_s, $str );
	}

	function protectStr( $str )
	{
		return base64_encode( $str );
	}
}